"""
忘记密码对话框
用户通过安全问题验证后可以重置密码
"""

import tkinter as tk
from tkinter import ttk, messagebox
import customtkinter
from core.utils.logger import info, warning, error
from ui.styles.theme import Theme


class ForgotPasswordDialog:
    """忘记密码对话框"""
    
    # 预设的安全问题列表
    SECURITY_QUESTIONS = [
        "你的第一只宠物叫什么名字？",
        "你的小学叫什么名字？",
        "你最喜欢的电影是什么？",
        "你母亲的娘家姓是什么？",
        "你出生的城市是哪里？"
    ]
    
    def __init__(self, parent, auth_service):
        self.parent = parent
        self.auth_service = auth_service
        self.result = False
        self.current_user = None
        
        # 创建对话框
        self.dialog = customtkinter.CTkToplevel(parent)
        self.dialog.title("Forgot Password")
        self.dialog.geometry("550x450")
        self.dialog.resizable(False, False)
        
        # 居中显示
        self.dialog.transient(parent)
        self.dialog.grab_set()
        self._center_dialog()
        
        # 步骤追踪
        self.step = 1  # 1: 输入用户名, 2: 验证安全问题, 3: 设置新密码
        
        self._create_widgets()
        self._show_step1()
    
    def _center_dialog(self):
        """居中显示对话框"""
        self.dialog.update_idletasks()
        width = 550
        height = 450
        x = (self.dialog.winfo_screenwidth() // 2) - (width // 2)
        y = (self.dialog.winfo_screenheight() // 2) - (height // 2)
        self.dialog.geometry(f"{width}x{height}+{x}+{y}")
    
    def _create_widgets(self):
        """创建对话框组件"""
        # 主容器
        main_frame = customtkinter.CTkFrame(self.dialog, fg_color="transparent")
        main_frame.pack(fill="both", expand=True, padx=30, pady=30)
        
        # 标题
        self.title_label = customtkinter.CTkLabel(
            main_frame,
            text="🔑 Forgot Password - Step 1",
            font=("Arial", 18, "bold"),
            text_color=Theme.get_color('fg_primary')
        )
        self.title_label.pack(pady=(0, 20))
        
        # 内容区域
        self.content_frame = customtkinter.CTkFrame(main_frame, fg_color="transparent")
        self.content_frame.pack(fill="both", expand=True, pady=(0, 15))
        
        # 按钮区域
        button_frame = customtkinter.CTkFrame(main_frame, fg_color="transparent")
        button_frame.pack(fill='x', pady=(15, 0))
        
        cancel_btn = customtkinter.CTkButton(
            button_frame,
            text="Cancel",
            command=self._cancel,
            width=120,
            height=35,
            fg_color=Theme.get_color('fg_secondary'),
            hover_color=Theme.get_color('fg_tertiary'),
            corner_radius=8
        )
        cancel_btn.pack(side="right", padx=(8, 0))
        
        self.next_btn = customtkinter.CTkButton(
            button_frame,
            text="Next",
            command=self._handle_next,
            width=120,
            height=35,
            fg_color=Theme.get_color('accent'),
            hover_color=Theme.get_color('accent_hover'),
            corner_radius=8
        )
        self.next_btn.pack(side="right")
    
    def _show_step1(self):
        """显示第1步：输入用户名"""
        self.step = 1
        self.title_label.config(text="忘记密码 - 第1步：输入用户名")
        
        # 清空内容区
        for widget in self.content_frame.winfo_children():
            widget.destroy()
        
        # 提示信息
        ttk.Label(
            self.content_frame,
            text="请输入您的用户名，我们将显示您的安全问题",
            font=("Arial", 10),
            foreground="#7F8C8D"
        ).pack(pady=(10, 20))
        
        # 用户名输入
        input_frame = ttk.Frame(self.content_frame)
        input_frame.pack(pady=10)
        
        ttk.Label(input_frame, text="用户名:", font=("Arial", 10)).grid(
            row=0, column=0, padx=5, pady=10, sticky="e"
        )
        self.username_entry = ttk.Entry(input_frame, width=30, font=("Arial", 10))
        self.username_entry.grid(row=0, column=1, padx=5, pady=10)
        self.username_entry.focus()
        
        # 绑定回车键
        self.username_entry.bind('<Return>', lambda e: self._handle_next())
    
    def _show_step2(self):
        """显示第2步：验证安全问题"""
        self.step = 2
        self.title_label.config(text="忘记密码 - 第2步：验证安全问题")
        
        # 清空内容区
        for widget in self.content_frame.winfo_children():
            widget.destroy()
        
        # 提示信息
        ttk.Label(
            self.content_frame,
            text="请回答您注册时设置的安全问题",
            font=("Arial", 10),
            foreground="#7F8C8D"
        ).pack(pady=(10, 20))
        
        # 显示安全问题
        question_frame = ttk.LabelFrame(
            self.content_frame,
            text="您的安全问题",
            padding=15
        )
        question_frame.pack(pady=10, fill="x", padx=20)
        
        ttk.Label(
            question_frame,
            text=self.current_user.security_question,
            font=("Arial", 11, "bold"),
            foreground="#2C3E50",
            wraplength=400
        ).pack(pady=10)
        
        # 答案输入
        input_frame = ttk.Frame(self.content_frame)
        input_frame.pack(pady=20)
        
        ttk.Label(input_frame, text="答案:", font=("Arial", 10)).grid(
            row=0, column=0, padx=5, pady=10, sticky="e"
        )
        self.answer_entry = ttk.Entry(input_frame, width=30, font=("Arial", 10))
        self.answer_entry.grid(row=0, column=1, padx=5, pady=10)
        self.answer_entry.focus()
        
        # 提示
        ttk.Label(
            self.content_frame,
            text="注意：答案不区分大小写",
            font=("Arial", 8),
            foreground="#95A5A6"
        ).pack()
        
        # 绑定回车键
        self.answer_entry.bind('<Return>', lambda e: self._handle_next())
    
    def _show_step3(self):
        """显示第3步：设置新密码"""
        self.step = 3
        self.title_label.config(text="忘记密码 - 第3步：设置新密码")
        self.next_btn.config(text="完成")
        
        # 清空内容区
        for widget in self.content_frame.winfo_children():
            widget.destroy()
        
        # 提示信息
        ttk.Label(
            self.content_frame,
            text="请设置您的新密码",
            font=("Arial", 10),
            foreground="#7F8C8D"
        ).pack(pady=(10, 20))
        
        # 新密码输入
        input_frame = ttk.Frame(self.content_frame)
        input_frame.pack(pady=10)
        
        # 新密码
        ttk.Label(input_frame, text="新密码:", font=("Arial", 10)).grid(
            row=0, column=0, padx=5, pady=10, sticky="e"
        )
        
        password_frame = ttk.Frame(input_frame)
        password_frame.grid(row=0, column=1, padx=5, pady=10, sticky="w")
        
        self.new_password_entry = ttk.Entry(password_frame, width=25, show="•", font=("Arial", 10))
        self.new_password_entry.pack(side="left")
        
        self.password_visible = False
        self.password_toggle_btn = ttk.Button(
            password_frame,
            text="👁",
            width=3,
            command=self._toggle_password_visibility
        )
        self.password_toggle_btn.pack(side="left", padx=2)
        
        # 确认密码
        ttk.Label(input_frame, text="确认密码:", font=("Arial", 10)).grid(
            row=1, column=0, padx=5, pady=10, sticky="e"
        )
        
        confirm_frame = ttk.Frame(input_frame)
        confirm_frame.grid(row=1, column=1, padx=5, pady=10, sticky="w")
        
        self.confirm_password_entry = ttk.Entry(confirm_frame, width=25, show="•", font=("Arial", 10))
        self.confirm_password_entry.pack(side="left")
        
        self.confirm_visible = False
        self.confirm_toggle_btn = ttk.Button(
            confirm_frame,
            text="👁",
            width=3,
            command=self._toggle_confirm_visibility
        )
        self.confirm_toggle_btn.pack(side="left", padx=2)
        
        # 密码强度显示
        self.password_strength_label = ttk.Label(
            self.content_frame,
            text="强度: 无",
            font=("Arial", 9, "bold"),
            foreground="#95A5A6"
        )
        self.password_strength_label.pack(pady=5)
        
        # 绑定密码输入事件
        self.new_password_entry.bind('<KeyRelease>', self._update_password_strength)
        
        # 提示
        ttk.Label(
            self.content_frame,
            text="密码要求：至少8位，包含字母、数字和特殊字符",
            font=("Arial", 8),
            foreground="#666666"
        ).pack(pady=10)
        
        self.new_password_entry.focus()
        
        # 绑定回车键
        self.confirm_password_entry.bind('<Return>', lambda e: self._handle_next())
    
    def _toggle_password_visibility(self):
        """切换新密码可见性"""
        self.password_visible = not self.password_visible
        if self.password_visible:
            self.new_password_entry.config(show="")
            self.password_toggle_btn.config(text="🔒")
        else:
            self.new_password_entry.config(show="•")
            self.password_toggle_btn.config(text="👁")
    
    def _toggle_confirm_visibility(self):
        """切换确认密码可见性"""
        self.confirm_visible = not self.confirm_visible
        if self.confirm_visible:
            self.confirm_password_entry.config(show="")
            self.confirm_toggle_btn.config(text="🔒")
        else:
            self.confirm_password_entry.config(show="•")
            self.confirm_toggle_btn.config(text="👁")
    
    def _update_password_strength(self, event=None):
        """更新密码强度显示"""
        from core.models.user import User
        password = self.new_password_entry.get()
        strength_level, strength_text, color = User.calculate_password_strength(password)
        self.password_strength_label.config(
            text=f"强度: {strength_text}",
            foreground=color
        )
    
    def _handle_next(self):
        """处理下一步按钮点击"""
        try:
            if self.step == 1:
                self._validate_step1()
            elif self.step == 2:
                self._validate_step2()
            elif self.step == 3:
                self._validate_step3()
        except Exception as e:
            messagebox.showerror("错误", str(e))
    
    def _validate_step1(self):
        """验证第1步：检查用户名是否存在"""
        username = self.username_entry.get().strip()
        
        if not username:
            messagebox.showwarning("输入错误", "请输入用户名")
            return
        
        # 查找用户
        user = self.auth_service.get_user_by_username(username)
        
        if not user:
            messagebox.showerror("用户不存在", "该用户名不存在，请检查后重试")
            return
        
        # 检查是否设置了安全问题
        if not user.security_question or not user.security_answer_hash:
            messagebox.showerror(
                "无法重置密码",
                "该账户未设置安全问题，无法通过此方式重置密码。\n请联系管理员。"
            )
            return
        
        # 保存当前用户并进入下一步
        self.current_user = user
        info(f"找到用户: {username}, 显示安全问题")
        self._show_step2()
    
    def _validate_step2(self):
        """验证第2步：检查安全问题答案"""
        answer = self.answer_entry.get().strip()
        
        if not answer:
            messagebox.showwarning("输入错误", "请输入答案")
            return
        
        # 验证答案
        if not self.current_user.verify_security_answer(answer):
            messagebox.showerror("验证失败", "安全问题答案不正确，请重试")
            self.answer_entry.delete(0, tk.END)
            self.answer_entry.focus()
            return
        
        # 验证成功，进入下一步
        info(f"安全问题验证成功: {self.current_user.username}")
        self._show_step3()
    
    def _validate_step3(self):
        """验证第3步：设置新密码"""
        new_password = self.new_password_entry.get()
        confirm_password = self.confirm_password_entry.get()
        
        if not new_password:
            messagebox.showwarning("输入错误", "请输入新密码")
            return
        
        if new_password != confirm_password:
            messagebox.showwarning("密码不匹配", "两次输入的密码不一致")
            self.new_password_entry.delete(0, tk.END)
            self.confirm_password_entry.delete(0, tk.END)
            self.new_password_entry.focus()
            return
        
        # 重置密码
        try:
            self.auth_service.reset_password(self.current_user.username, new_password)
            messagebox.showinfo(
                "密码重置成功",
                f"您的密码已成功重置！\n请使用新密码登录。"
            )
            self.result = True
            self.dialog.destroy()
        except ValueError as e:
            messagebox.showerror("重置失败", str(e))
    
    def _cancel(self):
        """取消操作"""
        self.result = False
        self.dialog.destroy()
    
    def show(self):
        """显示对话框并返回结果"""
        # 等待对话框关闭
        self.dialog.wait_window()
        return self.result

